#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os, sys
import time
import commands
import logging
import json

def getLogger(logFile='cron_load'):
    import logging.handlers
    logger = logging.getLogger(logFile)
    logger.setLevel(logging.DEBUG)
    LOGROOT = "/opt/epic/soc/log/cron"
    if not os.path.exists(LOGROOT):
        os.mkdir(LOGROOT)
    fh = logging.handlers.TimedRotatingFileHandler(os.path.normpath(LOGROOT + "/" + logFile + '.log'), 'midnight')
    fh.suffix = "%Y-%m-%d"
    fh.setLevel(logging.DEBUG)
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    fh.setFormatter(formatter)
    ch.setFormatter(formatter)
    logger.addHandler(fh)
    logger.addHandler(ch)
    return logger

logger = getLogger('cronMonitor')

def handle_sec(sec_list, num):
    flag = 0
    cron_list = []
    cmd = " ".join(sec_list[6:])
    if sec_list[1] == '*':
        sec_list[1] = '*/1'
    cmd_time = " ".join(sec_list[1:6])
    # print cmd_time
    if num == 1:
        cron_list.append(cmd_time + " " + cmd)
        try:
            sec = int(sec_list[0][2:])
        except Exception, e:
            # print "input error"
            logger.error("the rule can't identify cmd:%s" % cmd)
            return ''
            # sys.exit()
        if sec >= 60 or sec <= 0:
            # print "value error"
            logger.error("the second  error cmd:%s" % cmd)
            return ''
            # sys.exit()

        while flag + sec < 59:
            flag += sec
            cron_str = cmd_time + " sleep " + str(flag) + ";" + cmd
            cron_list.append(cron_str)
    elif num == 2:
        try:
            sec = int(sec_list[0])
        except Exception, e:
            # print "input error"
            logger.error("the rule can't identify cmd:%s" % cmd)
            return ''
            # sys.exit()
        if sec >= 60 or sec <= 0:
            # print "value error"
            logger.error("the second error... cmd:%s" % cmd)
            return ''
            # sys.exit()

        cron_list.append(cmd_time + " sleep " + str(sec - 1) + ";" + cmd)
    else:
        logger.error("the rule can't identify cmd:%s" % cmd)
        return ''

    return cron_list

def load_cron(node_status):
    line_list = []
    handle_list = []
    if node_status == 'master':
        master_cron_file = os.path.normpath('/opt/epic/soc/majordomo/conf/cron.conf')
        with open(master_cron_file, 'r') as fd:
            data_list = fd.readlines()
        if data_list[-1].find('\n') == -1:
            with open(master_cron_file, 'a') as fw:
                fw.write('\n')
        slave_cron_file = os.path.normpath('/opt/epic/soc/majordomo/conf/slave_cron.conf')
        with open(slave_cron_file, 'r') as fd:
            data_list.extend(fd.readlines())
        if data_list[-1].find('\n') == -1:
            with open(slave_cron_file, 'a') as fw:
                fw.write('\n')
        for line in data_list:
            if line[0] == '#' or line == '\n':
                continue
            line_list.append(line)
    else:
        cron_file = os.path.normpath('/opt/epic/soc/majordomo/conf/slave_cron.conf')
        with open(cron_file, 'r') as fd:
            data_list = fd.readlines()
        if data_list[-1].find('\n') == -1:
            with open(cron_file, 'a') as fw:
                fw.write('\n')
        for line in data_list:
            if line[0] == '#' or line == '\n':
                continue
            line_list.append(line)

    for line in line_list:
        sec_list = line.split(" ")
        sec = sec_list[0]
        if sec == '*':
            handle_list.append(line[2:])
        elif sec[:2] == '*/':
            handle_list += handle_sec(sec_list, 1)
        elif sec.isdigit():
            handle_list += handle_sec(sec_list, 2)

    crontab_file = os.path.normpath('/opt/epic/soc/majordomo/cron/.crontab')
    fd = open(crontab_file, 'w')
    for cmd in handle_list:
        cmd_list = cmd.split(' ', 5)
        cmd_list.insert(5, '. /etc/profile;')
        cmd = ' '.join(cmd_list)
        #fd.write(cmd + '\n')
        fd.write(cmd)
    fd.close()
    # 子节点无定时任务，所以该文件会不存在，会导致命令卡在crontab上
    if len(handle_list) == 0:
        crontab_file = os.path.normpath('/dev/null')
    output = commands.getoutput("crontab " + crontab_file)
    if output == '':
        logger.info("cron run successfully...")
        print 'crontab start success...'
    else:
        print 'crontab start fail... please check cron.log'
        logger.error(output)

def getnodeInfo():
    target_path = '/opt/epic/soc/majordomo/conf/nodes.json'
    ret = None
    try:
        f = file(target_path)
        ret = json.load(f)
    except Exception, e:
        logger.error("load nodes.json error ,resson : %s" % e)
    return ret

def main():
    #判断是主从节点,slave为从节点，master为主节点
    #安装未部署情况ip默认127.0.0.1
    nodeInfo = getnodeInfo()
    node_status = nodeInfo['type']
    ip = nodeInfo['ip']
    while ip == '127.0.0.1':
        nodeInfo = getnodeInfo()
        ip = nodeInfo['ip']
        node_status = nodeInfo['type']
        time.sleep(5)
    if node_status == 'master':
        cron_file = 'cat /opt/epic/soc/majordomo/conf/cron.conf  /opt/epic/soc/majordomo/conf/slave_cron.conf '
    else:
        cron_file = 'cat /opt/epic/soc/majordomo/conf/slave_cron.conf'
    init_file = ''
    while True:
        real_file = os.popen(cron_file).read()
        if real_file != init_file:
            init_file = real_file
            load_cron(node_status)
            logger.info('reload crontab success...')
        time.sleep(10)


if __name__ == '__main__':
    main()
"""
#this is crontab for configing your command
#you can organize command like * * * * * * cmd
#every * mean: sec, min, hour, day, month, week
#cmm: the string that you need execute
#for example:*/10 * * * * * python /home/test.py
#execute python /home/test.py once for every 10 seconds

#if you don't use second, rule like crontab
#for example:* */1 * * * * date >> /home/date.txt

#you have to abide to rules


* 0 */1 * * * python /opt/epic/soc/riskApp/calcu/calcu_risk.py
* 40 0 * * * python /opt/epic/soc/riskApp/calcu/calcu_threat.py
* 20 0 * * * python /opt/epic/soc/deps/threatAnalysis/bin/clean_history_data.py
* 30 23 * * * python /opt/epic/soc/majordomo/bin/del_by_time.py
* 0 0 * * * python /opt/epic/soc/deps/threatAnalysis/bin/crontask.py
* */30 * * * * python /opt/epic/soc/deps/threatAnalysis/bin/calcuRisk.py
* */2 * * * * python /opt/epic/soc/deps/threatAnalysis/bin/process_monitor.py
* */5 * * * * python /opt/epic/soc/majordomo/app/situationMgr/models/comprehensive_process.py minute
* */5 * * * * python /opt/epic/soc/majordomo/app/situationMgr/models/intrusion_process.py minute
* 30 */1 * * * python /opt/epic/soc/majordomo/app/situationMgr/models/comprehensive_situation.py other
* 30 */1 * * * python /opt/epic/soc/majordomo/app/situationMgr/models/intrusion_situation.py other
* 30 */1 * * * python /opt/epic/soc/majordomo/app/situationMgr/models/maliciouscode_situation.py other
* 30 0 * * * python /opt/epic/soc/majordomo/app/situationMgr/models/clear_situation.py

* */2 * * * * python /opt/epic/soc/majordomo/app/situationMgr/models/dashboard.py
* */30 * * * * python /opt/epic/soc/majordomo/app/situationMgr/models/asset_situation.py

* 1 1 * * * python /opt/epic/soc/bin/drop_history_event.py
* 10 */1 * * * python /opt/epic/soc/majordomo/app/users/loadNetflow.py
* 10 */1 * * * python /opt/epic/soc/majordomo/app/users/loadStreamEvent.py
* 0 */1 * * * python /opt/epic/soc/majordomo/app/users/models.py hour
* 0 8 * * * python /opt/epic/soc/majordomo/app/users/models.py day
1 30 2 * * * python /opt/epic/soc/majordomo/bin/process_rule_vul.py
* */5 * * * * python /opt/epic/soc/majordomo/bin/monitor_disk_space.py
* * */2 * * * find /var/spool/postfix/maildrop/ -type f |xargs rm -rf

* 30 22 * * * python /opt/epic/soc/vulnerabilityApp/vul_computer/WorkFlowUtils/wk_task.py
*/30 * * * * * bash /opt/epic/soc/vulnerabilityApp/device_ex/gettvm.sh
*/30 * * * * * bash /opt/epic/soc/vulnerabilityApp/device_ex/updatedevice.sh
* */1 * * * * python /opt/epic/soc/vulnerabilityApp/output_server/sync_data.py
* */1 * * * * python /opt/epic/soc/vulnerabilityApp/output_server/sender.py
* 0 */1 * * * python /opt/epic/soc/vulnerabilityApp/intelligence/app/intelligence_manager/cron_tasks/vul_intell_notify.py
* 0 0 */1 * * python /opt/epic/soc/vulnerabilityApp/intelligence/app/intelligence_manager/cron_tasks/expired_check.py
* 0 0 */1 * * python /opt/epic/soc/vulnerabilityApp/intelligence/app/intelligence_manager/cron_tasks/timing_pull.py
* */1 * * * * python /opt/epic/soc/vulnerabilityApp/vul_computer/vul_redis_go.py asset
* */5 * * * * python /opt/epic/soc/vulnerabilityApp/vul_computer/vul_redis_go.py vul
* */5 * * * * python /opt/epic/soc/vulnerabilityApp/device_ex/cron_task/license_expired.py
* 0 */1 * * * python /opt/epic/soc/vulnerabilityApp/vul_computer/backup_data.py
* 0 */1 * * * python /opt/epic/soc/vulnerabilityApp/scripts/delete_finished_tasks.py
* 50 0 * * * bash /opt/epic/soc/vulnerabilityApp/msg_task/bin/pack_up.sh
* */5 * * * * python /opt/epic/soc/vulnerabilityApp/task_manager/analysis/re_calcu.py
* */30 * * * *  iptables-restore < /etc/iptables

* */5 * * * * cd /opt/epic/soc/vulnerabilityApp/device_ex; python -m device_upgrade.task.sync_device
* 0 1 * * * cd /opt/epic/soc/vulnerabilityApp/device_ex; python -m device_upgrade.task.obtain_xml
* 0 2 * * * cd /opt/epic/soc/vulnerabilityApp/device_ex; python -m device_upgrade.task.obtain_pkg
* 0 3 2 * * cd /opt/epic/soc/vulnerabilityApp/device_ex; python -m device_upgrade.task.clear_pkg

1 45 3 * * * bash /opt/epic/soc/bin/clean_esp_logs.sh
* */1 * * * * bash /opt/epic/soc/vulnerabilityApp/scripts/rsas_log_backup.sh
"""